package matrice;
import controleur.QRCommon;
import dataMode.QRData;


public class QRCode {
	
	private Boolean[][] modules;
	private QRData data;
	private int size;
	
	public QRCode(QRData data) {
		this.data = data;
		this.size = (data.getVersion()*4)+17;
		this.modules = new Boolean[this.size][this.size];
		
		this.SetupDetectionPatterns();
		this.SetupTimingPatern();
		this.SetupInformationVersion();
	}
	
	public void SetupDetectionPatterns() {
		
		int i=0;
		int j;
		int s=(size-1);
		
		//detection patterns droite et gauche
		// 1er ligne		
		for(j=0;j<7;j++)
		{
			modules[i][j]=true;
		}
		modules[i][j]=false;
		j=s;
		while(j>(s-7))
		{
			modules[i][j]=true;
			j--;
		}
		modules[i][j]=false;
		//2éme ligne
		i++;j=0;s=(size-1);
		modules[i][j]=true;
		for(j=1;j<6;j++)
		{
			modules[i][j]=false;
		}
		modules[i][j]=true;
		j++;
		modules[i][j]=false;
		j=s;
		modules[i][j]=true;
		j=(s-1);
		while(j>(s-6))
		{
			modules[i][j]=false;
			j--;
		}
		modules[i][j]=true;
		j--;
		modules[i][j]=false;
		// 3, 4 et 5ème ligne
		for(i=2;i<5;i++)
		{
			j=0;s=(size-1);
			modules[i][j]=true;
			j++;
			modules[i][j]=false;
			for(j=2;j<5;j++)
			{
				modules[i][j]=true;
			}
			modules[i][j]=false;
			j++;
			modules[i][j]=true;
			j++;
			modules[i][j]=false;
			j=s;
			modules[i][j]=true;
			modules[i][j-1]=false;
			for(j=(s-2);j>(s-5);j--)
			{
				modules[i][j]=true;
			}
			modules[i][j]=false;
			j--;
			modules[i][j]=true;
			j--;
			modules[i][j]=false;
		}
		//6ème ligne
		j=0;s=(size-1);
		modules[i][j]=true;
		for (j=1;j<6;j++)
		{
			modules[i][j]=false;
		}
		modules[i][j]=true;
		j++;
		modules[i][j]=false;
		modules[i][s]=true;
		for(j=(s-1);j>(s-6);j--)
		{
			modules[i][j]=false;
		}
		modules[i][j]=true;
		j--;
		modules[i][j]=false;
		//7ème ligne
		i++;s=(size-1);
		for (j=0;j<7;j++)
		{
			modules[i][j]=true;
		}
		modules[i][j]=false;
		for (j=s;j>(s-7);j--)
		{
			modules[i][j]=true;
		}
		modules[i][j]=false;
		//8ème ligne
		i++;s=(size-1);
		for(j=0;j<8;j++)
		{
			modules[i][j]=false;
		}
		for(j=s;j>(s-8);j--)
		{
			modules[i][j]=false;
		}
		
		//detection patterns du bas à gauche
		//
		s=(size-1);i=s;
		for (j=0;j<7;j++)
		{
			modules[i][j]=true;
		}
		modules[i][j]=false;
		//
		j=0;i--;s=(size-1);
		modules[i][j]=true;
		for (j=1;j<6;j++)
		{
			modules[i][j]=false;
		}
		modules[i][j]=true;
		j++;
		modules[i][j]=false;
		// 
		for(i=(s-2);i>(s-5);i--)
		{
			j=0;s=(size-1);
			modules[i][j]=true;
			j++;
			modules[i][j]=false;
			for(j=2;j<5;j++)
			{
				modules[i][j]=true;
			}
			modules[i][j]=false;
			j++;
			modules[i][j]=true;
			j++;
			modules[i][j]=false;
		}
		//2-1
		j=0;s=(size-1);
		modules[i][j]=true;
		for (j=1;j<6;j++)
		{
			modules[i][j]=false;
		}
		modules[i][j]=true;
		j++;
		modules[i][j]=false;
		//
		j=0;s=(size-1);i--;
		for (j=0;j<7;j++)
		{
			modules[i][j]=true;
		}
		modules[i][j]=false;
		//
		j=0;i--;s=(size-1);
		for(j=0;j<8;j++)
		{
			modules[i][j]=false;
		}
		modules[i][j]=true;		
	}

	public void SetupTimingPatern()
	{
		int v=(data.getVersion()-1);
		if (v==0){
			modules[6][8]=true;
			modules[6][9]=false;
			modules[6][10]=true;
			modules[6][11]=false;
			modules[6][12]=true;
			modules[8][6]=true;
			modules[9][6]=false;
			modules[10][6]=true;
			modules[11][6]=false;
			modules[12][6]=true;
		}
		else if(v > 0){	
		int l=QRCommon.PATTERN_POSITION_TABLE[v][0];
		int c=QRCommon.PATTERN_POSITION_TABLE[v][0];
		if (modules[l][c]!=null)
		{
			while(modules[l][c]!=null)
			{
				c++;
			}
			while(modules[l][c]==null)
			{
				modules[l][c]=true;
				modules[l][c+1]=false;
				c=c+2;
			}
			c=QRCommon.PATTERN_POSITION_TABLE[v][0];
			while(modules[l][c]!=null)
			{
				l++;
			}
			while(modules[l][c]==null)
			{
				modules[l][c]=true;
				modules[l+1][c]=false;
				l=l+2;
			}	
		}
		for(int a=1; a<QRCommon.PATTERN_POSITION_TABLE[v].length; a++)
		{
			l=QRCommon.PATTERN_POSITION_TABLE[v][a];
			c=QRCommon.PATTERN_POSITION_TABLE[v][a];
			modules[l-2][c-2]=true;
			modules[l-1][c-2]=true;
			modules[l][c-2]=true;
			modules[l+1][c-2]=true;
			modules[l+2][c-2]=true;
			modules[l-2][c-1]=true;
			modules[l-1][c-1]=false;
			modules[l][c-1]=false;
			modules[l+1][c-1]=false;
			modules[l+2][c-1]=true;
			modules[l-2][c]=true;
			modules[l-1][c]=false;
			modules[l][c]=true;
			modules[l+1][c]=false;
			modules[l+2][c]=true;
			modules[l-2][c+1]=true;
			modules[l-1][c+1]=false;
			modules[l][c+1]=false;
			modules[l+1][c+1]=false;
			modules[l+2][c+1]=true;
			modules[l-2][c+2]=true;
			modules[l-1][c+2]=true;
			modules[l][c+2]=true;
			modules[l+1][c+2]=true;
			modules[l+2][c+2]=true;
			
			if(data.getVersion()>6){
				int prec=QRCommon.PATTERN_POSITION_TABLE[v][a-1];
				c=prec;
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;
				modules[l+2][c+2]=true;
			
				l=prec;
				c=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;		
				modules[l+2][c+2]=true;
			}
			if(data.getVersion()>13 & a >=2){
				int prece=QRCommon.PATTERN_POSITION_TABLE[v][a-2];
				c=prece;
				l=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;
				modules[l+2][c+2]=true;
				
				l=prece;
				c=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;		
				modules[l+2][c+2]=true;
			}
			if(data.getVersion()>20 & a >=3){
				int prece=QRCommon.PATTERN_POSITION_TABLE[v][a-3];
				c=prece;
				l=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;
				modules[l+2][c+2]=true;
				
				l=prece;
				c=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;		
				modules[l+2][c+2]=true;
			}
			if(data.getVersion()>27 & a >=4){
				int prece=QRCommon.PATTERN_POSITION_TABLE[v][a-4];
				c=prece;
				l=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;
				modules[l+2][c+2]=true;
				
				l=prece;
				c=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;		
				modules[l+2][c+2]=true;
			}
			if(data.getVersion()>34 & a >=5){
				int prece=QRCommon.PATTERN_POSITION_TABLE[v][a-5];
				c=prece;
				l=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;
				modules[l+2][c+2]=true;
				
				l=prece;
				c=QRCommon.PATTERN_POSITION_TABLE[v][a];
				modules[l-2][c-2]=true;
				modules[l-1][c-2]=true;
				modules[l][c-2]=true;
				modules[l+1][c-2]=true;
				modules[l+2][c-2]=true;
				modules[l-2][c-1]=true;
				modules[l-1][c-1]=false;
				modules[l][c-1]=false;
				modules[l+1][c-1]=false;
				modules[l+2][c-1]=true;
				modules[l-2][c]=true;
				modules[l-1][c]=false;
				modules[l][c]=true;
				modules[l+1][c]=false;
				modules[l+2][c]=true;
				modules[l-2][c+1]=true;
				modules[l-1][c+1]=false;
				modules[l][c+1]=false;
				modules[l+1][c+1]=false;
				modules[l+2][c+1]=true;
				modules[l-2][c+2]=true;
				modules[l-1][c+2]=true;
				modules[l][c+2]=true;
				modules[l+1][c+2]=true;		
				modules[l+2][c+2]=true;
			}
		}
		}
	}
	
	public void SetupInformationVersion()
	{
		int i=0;
		int l=0;
		if (data.getVersion()>=7){
			int iv=(data.getVersion()- 7);
			while((l<7) && (i<QRCommon.BIT_INFORMATION_VERSION[iv].length))
			{
				for(int c=(size-11);c<(size-8);c++)
				{
					int biv=QRCommon.BIT_INFORMATION_VERSION[iv][i];
					if(biv==1)
					{
						modules[l][c]=true;
						i++;
					}else
					{
						modules[l][c]=false;
						i++;
					}
				}
				l++;
			}	
			int c=0;i=0;
			while((c<7) && (i<QRCommon.BIT_INFORMATION_VERSION[iv].length))
			{
				for(l=(size-11);l<(size-8);l++)
				{
					int biv=QRCommon.BIT_INFORMATION_VERSION[iv][i];		
					if(biv==1)
					{
						modules[l][c]=true;
						i++;
					}else
					{
						modules[l][c]=false;
						i++;
					}
				}
				c++;
			}
		}
	}
	
	public void afficher() {
		for(int i=0; i<size; i++) {
			for(int j=0; j<size; j++) {
				if(modules[i][j] != null) {	
					if(modules[i][j] == true)
						System.out.print("1");
					else if(modules[i][j] == false)
						System.out.print("0");
					}
					else {
						System.out.print(" ");
					}
			}
			System.out.println(" ");
		}
	}
	
	public Boolean[][] getMatrice(){	
		return this.modules;
	}
}
